package com.lg.gc.gcweb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * 当前的的系统模仿线上系统 频繁full gc ，7x24小时在线。
 * <p>
 * 机器配置：2核4G
 * JVM内存大小：2G
 * 系统运行时间：7天
 * 期间发生的Full GC次数和耗时：500多次，200多秒
 * 期间发生的Young GC次数和耗时：1万多次，500多秒
 * <p>
 * 大致算下来就是每天发生70多次full gc 平均每小时3次，每次Full GC在400毫秒左右；
 * 每天发生1000多次young gc，没分钟会发生一次，每次minor gc在50毫秒左右
 * <p>
 * 模拟参数，优化前：
 * -Xms1536M -Xmx1536M -Xmn512M -Xss256K -XX:SurvivorRatio=6  -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M
 * -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC  -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly
 * <p>
 * 查看jvm 参数是否生效
 * jinfo -flags <pid>
 * 65536.0 65536.0  0.0   65536.0 393216.0 393214.1 1048576.0  1048514.0  31872.0 29112.0 4480.0 3938.0    267    0.782 1293    46.908   47.689
 * 第一次参数中，full gc 频繁，发生full gc 就要开始思考，哪些对象在什么情况下 会被移到老年代。 大对象 或者大量对象中的动态年轻担保机制
 * 首先考虑对象太大的情况，将年轻代调大一点（保证对象在没有进入老年代之前被minor gc 回收掉）
 * <p>
 * -Xms1536M -Xmx1536M -Xmn1024M -Xss256K -XX:SurvivorRatio=6  -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC  -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly
 * 结果：
 * 131072.0 131072.0  0.0    0.0   786432.0 280625.9  524288.0   510996.2  31232.0 28968.7 4352.0 3904.5      7    0.237  17      0.640    0.877
 * 131072.0 131072.0  0.0    0.0   786432.0 368003.0  524288.0   510396.1  31232.0 28968.7 4352.0 3904.5      8    0.237  20      0.720    0.957
 * 发现还是有大量的gc 出现，那么排除是有大内存对象，那么很有可能是大量的对象生成，导致的动态年龄分配的问题（此时 full gc 比minor gc 还多）
 * 导致 minor gc 比 full gc 还少的 几种情况？
 * 1. 元空间不够导致的多余full gc
 * 2. 显示调用system.gc（），这种情况一般在线上配置-XX:+DisableExplicitGC参数禁用，
 * 3. 老年代空间分配担保机制
 *
 */
@SpringBootApplication
public class GcWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(GcWebApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}
